// file:include/lib/math.h
//: autor:jiang xinpeng
// time:2020.12.27
// copyright:(C) 2020-2050 by jiang xinpeng,All are reserved.

#ifndef LIB_MATH_H
#define LIB_MATH_H

#include <lib/type.h>

#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif

#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif

#ifndef ABS
#define ABS(a) ((a) > 0 ? (a) : -(a))
#endif

#define min MIN
#define max MAX
#define abs ABS

#define DIV_ROUND_UP(x, step) ((x + step - 1) / (step))
#define DIV_ROUND_DOWN(x, step) (x / step)

#define ALIGH_WITH(x, y) (x + (y - 1) & (~(y - 1)))

#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))

#define IS_POWER_OF_2(n) ((n) != 0 && !(n % 2))

static inline int64_t fls(int64_t x)
{
    int64_t position;
    int64_t i;
    if (x != 0)
    {
        for (i = (x >> 1), position = 0; i != 0; position++)
        {
            i >>= 1;
        }
    }
    else
        position = -1;
    return position + 1;
}

static inline uint64_t roundup_pow_of_two(uint64_t x)
{
    return 1 << fls(x - 1);
}

static inline int powi(int x, int n)
{
    int res = 1;
    if (n < 0)
    {
        x = 1 / x;
        n = -n;
    }
    while (n)
    {
        if (n & 1)
            res *= x;
        x *= x;
        n >>= 1;
    }
    return res;
}

// return figrure mod
static inline uint32_t do_div(uint32_t *num, uint32_t base)
{
    uint32_t res;
    res = *num % base;
    *num = *num / base;
    return res;
}

#endif